<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
         let obj = {
            name: 'geyao'
        }

        let name = 'test'
        function fn() {
            console.log(this.name);
        }
        // call() 和apply()的第一个参数相同，就是指定的对象。这个对象就是该函数的执行上下文。

        // call()和apply()的区别就在于，两者之间的参数。call()在第一个参数之后的 后续所有参数就是传入该函数的值。apply() 只有两个参数，第一个是对象，第二个是数组，这个数组就是该函数的参数。

        // bind() 方法和前两者不同在于：bind()方法会返回执行上下文被改变的函数而不会立即执行，而前两者是直接执行该函数。他的参数和call()相同。
        Function.prototype.myCall = function (context) {
            if (typeof this !== 'function') {
                throw new TypeError('Error')
            }
            context = context || window
            // 谁调用call方法，this就指向谁
            context.fn = this
            // 去掉所有参数中第一参数（指定的对象）
            const args = [...arguments].slice(1)
            const result = context.fn(...args)
            delete context.fn
            return result
        }

    </script>
</body>

</html>